#include "operatefile.h"

OperateFile::OperateFile()
        :xml_path_("./sftpconfig.xml")
{
}

void OperateFile::ScanFile()
{
    QDir dir(file_path);
    QStringList filters;
    QString remove_type = "cny";
    filters << "*.fsn";//<<"*cpp"
    dir.setNameFilters(filters);
    QStringList file_list = dir.entryList();

    QStringList::iterator i;
    for (i = file_list.begin(); i != file_list.end(); i++) {
        QString file_path_temp = file_path + *i;
        if (!(*i).contains(remove_type, Qt::CaseInsensitive)) {
            qDebug() << "file : " << *i << " not contain cny.";
            RemoveAndBackupFile(file_path_temp);
            continue;
        }
        qDebug() << "file : " << *i << " wait to upload.";
        int rc = uploadFile(*i);
        switch (rc) {
            case 1:
                qDebug() << file_path_temp << " upload success.";
            case 2:
                RemoveAndBackupFile(file_path_temp);
                break;
            case -5:
                qDebug() << " sftp init failed ,sftp reopen!";
                break;
            case -8:
                qDebug() << file_path_temp << "upload failed ,please check network, sftp server and restart.";
                break;
            case -9:
                qDebug() << file_path_temp << "fstp open failed,check ip, port_, username, password! please restart! ";
                break;
            default:
                break;
        }
    }
}


void OperateFile::CheckPath()
{
    file_path.replace(QRegExp("\\"), "/");
    file_path_backup.replace(QRegExp("\\"), "/");
    sftp_path.replace(QRegExp("\\"), "/");
    if (!file_path.endsWith("/"))
        file_path += "/";
    if (!file_path_backup.endsWith("/"))
        file_path_backup += "/";
    if (!sftp_path.endsWith("/"))
        sftp_path += "/";
}

const char *OperateFile::ReadXmlValue(XMLElement *root, const char *element)
{
    if (root->FirstChildElement(element) == NULL) {
        qDebug() << "not find:" << element;
        return "";
    }
    else {
        return root->FirstChildElement(element)->GetText();
    }

    // (root->FirstChildElement(element))->Attribute("value");
}

const int OperateFile::ReadFromXml()
{
    tinyxml2::XMLDocument doc;
    int res = doc.LoadFile(xml_path_.toStdString().c_str());
    if (res != 0) {
        qDebug() << "load xml file failed";
        return -1;
    }
    XMLElement *root = doc.RootElement();
    host_ip_ = QString(ReadXmlValue(root, "ip"));
    port_ = QString(ReadXmlValue(root, "port_"));
    user_name_ = QString(ReadXmlValue(root, "username"));
    pass_word = QString(ReadXmlValue(root, "password"));
    file_path = QString(ReadXmlValue(root, "scanPath"));
    file_path_backup = QString(ReadXmlValue(root, "scanPathBackup"));
    sftp_path = QString(ReadXmlValue(root, "sftpPath"));

    user_auth = QString(ReadXmlValue(root, "userAuth"));
    public_file_path = QString(ReadXmlValue(root, "publicKeyPath"));
    private_file_path = QString(ReadXmlValue(root, "privateKeyPath"));
    pass_phrase = QString(ReadXmlValue(root, "passPhrase"));
    circle_time = QString(ReadXmlValue(root, "circleTime"));
    CheckPath();
    return 1;
}

const int OperateFile::GetCircleTime()
{
    int time_temp = 2;
    if (circle_time.toInt() != 0)
        time_temp = circle_time.toInt();
    return 60 * 1000 * time_temp;
}

void OperateFile::LoadConfFromW(
        QString host_ip_, QString port_, QString user_name_, QString pass_word_, QString file_path_
        , QString file_path_backup_, QString sftp_path_, QString user_auth, QString public_file_path
        , QString private_file_path, QString pass_phrase, QString circle_time)
{

    host_ip_ = host_ip_;
    port_ = port_;
    user_name_ = user_name_;
    pass_word = pass_word_;
    file_path = file_path_;
    file_path_backup = file_path_backup_;
    sftp_path = sftp_path_;
    user_auth = user_auth;
    public_file_path = public_file_path;
    private_file_path = private_file_path;
    pass_phrase = pass_phrase;
    circle_time = circle_time;

    CheckPath();
    SaveAsSftpConf();
    qDebug() << "saved to xml:" << host_ip_ << " " << port_ << " " << user_name_ << pass_word << file_path
             << file_path_backup << sftp_path << user_auth << public_file_path << private_file_path << pass_phrase;
}

/**
 * 保存xml文件
 * @brief OperateFile::SaveAsSftpConf
 * @return
 */

void OperateFile::SaveXmlOneByOne(tinyxml2::XMLDocument *doc, tinyxml2::XMLElement *root, const char *element, QString s)
{
    qDebug() << s;
    if (s == NULL || s == "") {
        return;
    }
    tinyxml2::XMLElement *el = doc->NewElement(element);
    el->InsertEndChild(doc->NewText(s.toStdString().c_str()));
    root->InsertEndChild(el);
}

int OperateFile::SaveAsSftpConf()
{
    tinyxml2::XMLDocument doc;
    tinyxml2::XMLElement *root = doc.NewElement("sftp");
    SaveXmlOneByOne(&doc, root, "ip", host_ip_);
    SaveXmlOneByOne(&doc, root, "port_", port_);
    SaveXmlOneByOne(&doc, root, "username", user_name_);
    SaveXmlOneByOne(&doc, root, "password", pass_word);
    SaveXmlOneByOne(&doc, root, "scanPath", file_path);
    SaveXmlOneByOne(&doc, root, "scanPathBackup", file_path_backup);
    SaveXmlOneByOne(&doc, root, "sftpPath", sftp_path);

    //秘钥
    SaveXmlOneByOne(&doc, root, "userAuth", user_auth);
    SaveXmlOneByOne(&doc, root, "publicKeyPath", public_file_path);
    SaveXmlOneByOne(&doc, root, "privateKeyPath", private_file_path);
    SaveXmlOneByOne(&doc, root, "passPhrase", pass_phrase);
    SaveXmlOneByOne(&doc, root, "circleTime", circle_time);
    doc.InsertEndChild(root);
    doc.SaveFile(xml_path_.toStdString().c_str());
    return 0;
}

const int OperateFile::SftpOpen()
{
    if (initSession() != 1) {
        qDebug() << "Init session failed!";
        return -1;
    }
    else {
        QDir dir;
        if (!dir.exists(file_path)) {
            bool res = dir.mkpath(file_path);
            qDebug() << "i do not found scanPath,mkdir scanPath:" << res;
        }
        if (!dir.exists(file_path_backup)) {
            bool res = dir.mkpath(file_path_backup);
            qDebug() << "i do not found scanPathBackup,mkdir scanPathBackup:" << res;
        }
        qDebug() << "Init session successed!";
        return 1;
    }
}

//void OperateFile::sftpReopen() {
//    delete sftpc;
//    sftpc = NuLL;
//    SftpOpen();
//}

const int OperateFile::RemoveAndBackupFile(QString slocalfile)
{
    QString old_name(slocalfile);
    QString new_name(slocalfile);
    new_name = new_name.split('/').last();
    new_name.append(".bak");
    new_name.prepend(file_path_backup);
    // 检查目录是否存在，若不存在则新建
    QDir dir;
    if (!dir.exists(file_path_backup)) {
        bool res = dir.mkpath(file_path_backup);
        qDebug() << "i do not found scanPathBackup,mkdir scanPathBackup:" << res;
    }

    //移动旧文件到备份文件夹
    if (QFile::rename(old_name, new_name)) {
        return 1;
    }
    else {
        //备份文件夹中文件已存在，则覆盖旧文件
        qDebug() << new_name << " exists";
        if (QFile::remove(new_name)) {
            qDebug() << new_name << " remove success";
        }
        else {
            //同名文件无删除权限，则文件名后加bak;
            qDebug() << new_name << "same file remove fail,add bak to new file";
            new_name.append(".bak");
        }
        QFile::rename(old_name, new_name);
        return 1;
    }
}

//QString host_ip_;
//QString port_;
//QString user_name_;
//QString pass_word;
//QString sftp_path;
QString OperateFile::getIp()
{
    return host_ip_;
}

QString OperateFile::getPort()
{
    return port_;
}

QString OperateFile::getUserName()
{
    return user_name_;
}

QString OperateFile::getPassWord()
{
    return pass_word;
}

QString OperateFile::getSftpPath()
{
    return sftp_path;
}

//QString file_path;//上传文件目录
//QString file_path_backup;//备份文件目录
//QString user_auth;//0表示密码 1表示公钥
//QString public_file_path;
QString OperateFile::getFilePath()
{
    return file_path;
}

QString OperateFile::getFilePathBackup()
{
    return file_path_backup;
}

QString OperateFile::getUserAuth()
{
    return user_auth;
}

QString OperateFile::getPublicFilePath()
{
    return public_file_path;
}

//QString private_file_path;
//QString pass_phrase;
//QString circle_time;//扫描循环时间,单位为分钟
QString OperateFile::getPrivateFilePath()
{
    return private_file_path;
}

QString OperateFile::getPassPhrase()
{
    return pass_phrase;
}

QString OperateFile::getCircleTimeS()
{
    return circle_time;
}

OperateFile::~OperateFile()
{

}
